package com.ruoyi.web.controller.system;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.Dto.SpendDetailDto;
import com.ruoyi.system.domain.Dto.SysSpendDto;
import com.ruoyi.system.domain.Dto.TimeDto;
import com.ruoyi.system.domain.SpendDetail;
import com.ruoyi.system.domain.SysSpend;
import com.ruoyi.system.domain.SysTotalBill;
import com.ruoyi.system.domain.vo.BillStatistic;
import com.ruoyi.system.domain.vo.SysSpendVo;
import com.ruoyi.system.service.SpendService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author chenyouliang
 * @create 2024/11/14 9:54
 */
@RestController
@Slf4j
@Api(tags = "账单管理")
@RequestMapping("/system/spend")
public class SysSpendController extends BaseController {

    @Autowired
    private SpendService spendService;

    /**
     * 获取花销列表
     */
    @ApiOperation("获取账单列表")
    @GetMapping("/list")
    public TableDataInfo list(SysSpend sysSpend) {
        // startPage();
        List<SysSpend> list = spendService.selectSpendList(sysSpend);
        return getDataTable(list);
    }

    /**
     * 获取花销列表树
     */
    @ApiOperation("获取账单列表树")
    @GetMapping("/listTree")
    public TableDataInfo listTree(SysSpend sysSpend) {
        // startPage();
        List<SysSpend> list = spendService.listTree(sysSpend);
        return getDataTable(list);
    }

    /**
     * 新增花销列表
     */
    @Log(title = "花销管理", businessType = BusinessType.INSERT)
    @ApiOperation("新增账单")
    @PostMapping
    public AjaxResult add(@Validated @RequestBody SysSpendDto spendDto) {
        spendDto.setCreateBy(getUsername());
        spendDto.setUserId(getUserId());
        return toAjax(spendService.insertSpend(spendDto));
    }

    /**
     * 删除花销
     */
    @Log(title = "花销管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    @ApiOperation("删除账单列表")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(spendService.deleteByIds(ids));
    }

    /**
     * 删除单个花销详情
     */
    @Log(title = "花销管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/spendDetail/{id}")
    @ApiOperation("删除账单列表详情")
    public AjaxResult deleteDetailById(@PathVariable Integer id) {
        return toAjax(spendService.deleteDetailById(id));
    }

    /**
     * 修改单个花销详情
     */
    @Log(title = "花销管理", businessType = BusinessType.UPDATE)
    @PutMapping("/spendDetail/update")
    @ApiOperation("修改账单列表详情")
    public AjaxResult editDetail(@Validated @RequestBody SpendDetail spendDetail) {
        return toAjax(spendService.editDetail(spendDetail));
    }

    /**
     * 根据id获取详细信息
     */
    @GetMapping(value = "/{id}")
    @ApiOperation("获取账单列表详情")
    public AjaxResult getInfo(@PathVariable Integer id) {
        SysSpendVo spendVo = spendService.getInfo(id);
        return AjaxResult.success(spendVo);
    }

    /**
     * 修改花销列表
     */
    @Log(title = "花销管理", businessType = BusinessType.UPDATE)
    @ApiOperation("修改账单列表")
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody SysSpendDto spendDto) {
        spendDto.setUpdateBy(getUsername());
        spendService.updateSpend(spendDto);
        return AjaxResult.success();
    }

    /**
     * 获取账单详情列表
     *
     * @param spendDetailDto
     * @return
     */
    @ApiOperation("获取账单详情列表")
    @GetMapping("/spendDetail/list")
    public TableDataInfo detailList(SpendDetailDto spendDetailDto) {
        startPage();
        List<SpendDetail> list = spendService.selectDetailList(spendDetailDto);
        return getDataTable(list);
    }

    /**
     * 新增账单详情列表
     *
     * @param spendDetail
     * @return
     */
    @ApiOperation("新增账单详情列表")
    @PostMapping("/spendDetail/add")
    public AjaxResult addDetailList(@Validated @RequestBody SpendDetail spendDetail) {
        return toAjax(spendService.addDetailList(spendDetail));
    }

    /**
     * 获取总账单列表
     *
     * @param sysTotalBill
     * @return
     */
    @ApiOperation("获取总账单列表")
    @GetMapping("/totalBill/list")
    public TableDataInfo totalBillList(SysTotalBill sysTotalBill) {
        startPage();
        List<SysTotalBill> list = spendService.totalBillList(sysTotalBill);
        return getDataTable(list);
    }

    /**
     * 获取总账单列表详情
     *
     * @param sysTotalBill
     * @return
     */
    @ApiOperation("获取总账单列表详情")
    @PostMapping("/totalBill/detail")
    public AjaxResult totalBillDetail(@RequestBody SysTotalBill sysTotalBill) {
        SysTotalBill sysTotalDetail = spendService.totalBillDetail(sysTotalBill);
        return AjaxResult.success(sysTotalDetail);
    }

    /**
     * 新增总账单
     *
     * @param sysTotalBill
     * @return
     */
    @ApiOperation("新增总账单")
    @PostMapping("/totalBill/add")
    public AjaxResult totalBillAdd(@RequestBody SysTotalBill sysTotalBill) {
        sysTotalBill.setCreateBy(getUsername());
        return toAjax(spendService.totalBillAdd(sysTotalBill));
    }

    /**
     * 修改总账单
     *
     * @param sysTotalBill
     * @return
     */
    @ApiOperation("修改总账单")
    @PostMapping("/totalBill/update")
    public AjaxResult totalBillUpdate(@RequestBody SysTotalBill sysTotalBill) {
        sysTotalBill.setUpdateBy(getUsername());
        return toAjax(spendService.totalBillUpdate(sysTotalBill));
    }

    /**
     * 获取总账单统计
     *
     * @param yearTime
     * @return
     */
    @ApiOperation("获取总账单统计")
    @GetMapping("/billStatistic/statistic")
    public AjaxResult getStatistic(String yearTime) {
        BillStatistic billStatistic = spendService.getStatistic(yearTime);
        return AjaxResult.success(billStatistic);
    }

    /**
     * 获取每个月账单统计
     *
     * @param monthTime
     * @return
     */
    @ApiOperation("获取每个月账单统计")
    @GetMapping("/billStatistic/month")
    public TableDataInfo getMonthStatistic(String monthTime) {
        List<SysSpend> list = spendService.getMonthStatistic(monthTime);
        return getDataTable(list);
    }

    /**
     * 获取每年账单前五统计
     *
     * @param yearTime
     * @return
     */
    @ApiOperation("获取每年账单前五统计")
    @GetMapping("/billStatistic/yearTop")
    public TableDataInfo getTop(String yearTime) {
        List<SysTotalBill> list = spendService.getTop(yearTime);
        return getDataTable(list);
    }

    @ApiOperation("获取每月花销的总金额")
    @PostMapping("/getTotalActual")
    public AjaxResult getTotalActual(@RequestBody TimeDto timeDto) {
        String totalActual = spendService.getTotalActual(timeDto);
        Map<String, String> map = new HashMap<>();
        map.put("totalActual", totalActual);
        return AjaxResult.success(map);
    }

    @ApiOperation("模糊查询获取账单详情")
    @PostMapping("/getSpendDetail")
    public TableDataInfo getSpendDetail(@RequestBody SpendDetailDto spendDetail) {
        TableDataInfo tableDataInfo = new TableDataInfo();
        List<SysSpendVo> result = spendService.getSpendDetail(spendDetail);
        tableDataInfo.setTotal(result.size());
        result = result.stream().sorted(Comparator.comparing(SysSpendVo::getSpendingTime, Comparator.nullsLast(LocalDate::compareTo)).reversed()).collect(Collectors.toList());
        result = result.stream().skip(spendDetail.getPageSize() * (spendDetail.getPageNum() - 1)).limit(spendDetail.getPageSize()).collect(Collectors.toList());
        tableDataInfo.setRows(result);
        tableDataInfo.setCode(200);
        tableDataInfo.setMsg("查询成功");
        return tableDataInfo;
    }

}
